<template>
  <div class="gridContainer">
    <!--基本功能：
                单表头，多表头，可编辑，分页，过滤，只读列，排序，锁定，合计，溢出隐藏显示点点点，必填及校验，
                序号和复选框，拉动列大小，隔行变色，修改数据有标记，新增，删除，保存。 theme: 'dark/light'
    -->
    <!--高级表格-->
    <vxe-grid
      auto-resize
      resizable
      keep-source
      export-config
      header-align="center"
      class="grid-class-name"
      :ref="gridRef"
      :stripe="stripe"
      :border="border"
      :highlight-current-row="isHighLightCurrRow"
      :highlight-hover-row="isHighLighthoverRow"
      :highlight-current-column="isHighLightCurrcolumn"
      :highlight-hover-column="isHighLighthovercolumn"
      :show-overflow="showOverflow"
      :size="size"
      :cell-style="cellStyle"
      :header-cell-style="headerCellStyle"
      :footer-cell-style="footerCellStyle"
      :row-style="rowStyle"
      :header-row-style="tableConfigObj.tableSetting.headerRowStyle"
      :footer-row-style="tableConfigObj.tableSetting.footerRowStyle"
      :cell-class-name="cellClassName"
      :header-cell-class-name="headerCellClassName"
      :footer-cell-class-name="footerCellClassName"
      :row-class-name="rowClassName"
      :header-row-class-name="tableConfigObj.tableSetting.headerRowClassName"
      :footer-row-class-name="tableConfigObj.tableSetting.footerRowClassName"
      :show-header-overflow="showOverflow"
      :span-method="rowSpanMethod"
      :footer-method="footerMethod"
      :footer-span-method="footerSpanMethod"
      :align="allAlign"
      :loading="loading"
      :height="height"
      :max-height="max_height"
      :edit-rules="validRules"
      :data="tableDataList"
      :columns="columnDataList"
      :toolbar-config="tableConfigObj.tableToolbar"
      :tree-config="tableConfigObj.treeConfig"
      :show-header="tableConfigObj.tableSetting.showHeader"
      :style="tableConfigObj.tableSetting.tableHeight"
      :show-footer="tableConfigObj.tableSetting.totalTag === 1"
      :row-id="tableConfigObj.tableSetting.rowId"
      :seq-config="{
        startIndex: tableConfigObj.tableSetting.isSeqConfig
          ? tableConfigObj.tablePage.pageSize *
            (tableConfigObj.tablePage.currentPage - 1)
          : null,
      }"
      :checkbox-config="{
        trigger: tableConfigObj.tableSetting.rowChecked,
        highlight: checkStyle === 'checkbox',
        range: false,
        showHeader: tableConfigObj.tableSetting.showCheckboxHeader,
        labelField: tableConfigObj.tableSetting.checkLabel,
        checkMethod: loadCheckMethod,
      }"
      :radio-config="{
        trigger: tableConfigObj.tableSetting.rowChecked,
        highlight: checkStyle === 'radio',
        labelField: tableConfigObj.tableSetting.radioLabel,
        checkMethod: loadCheckMethod,
        checkRowKey: tableConfigObj.tableSetting.checkRowKey,
      }"
      :edit-config="{
        //trigger: 'manual', mode: 'row',
        trigger: tableConfigObj.tableSetting.trigger,
        mode: tableConfigObj.tableSetting.mode,
        showStatus: true,
        beforeEditMethod: activeCellMethod,
      }"
      :keyboard-config="{
        isArrow: false,
        isDel: true,
        isEnter: true,
        isTab: true,
        isEdit: true,
      }"
      :tooltip-config="{
        theme: 'light',
        enabled: false,
        enterable: false,
        contentMethod: tooltipContentMethod,
      }"
      :empty-render="{
        name: 'myEmptyData',
        props: { content: emptyRenderCon },
      }"
      :scroll-x="{
        enable: false,
        gt: -1,
      }"
      :scroll-y="{
        enable: false,
        gt: -1,
      }"
      @cell-click="cellClickEvent"
      @header-cell-click="headerCellClickEvent"
      @footer-cell-click="footerCellClickEvent"
      @cell-dblclick="cellDBLClickEvent"
      @header-cell-dblclick="headerCellDBLClickEvent"
      @footer-cell-dblclick="footerCellDBLClickEvent"
      @cell-mouseenter="cellMouseenterEvent"
      @cell-mouseleave="cellMouseleaveEvent"
      @checkbox-all="checkboxAll"
      @checkbox-change="checkboxChange"
      @scroll="scrollEvent"
      @edit-actived="editActivedEvent"
      @edit-closed="editClosedEvent"
    >
      <!--工具栏之左侧普通按钮-->
      <template v-slot:buttons>
        <!--自定义插槽，样式有问题。-->
        <div class="title" v-show="tableConfigObj.tableSetting.isShowGridTitle">
          <!-- <img src="@/assets/img/title-icon.png" /> -->
          <span>{{
            tableConfigObj.tableSetting.title
              ? tableConfigObj.tableSetting.title
              : ""
          }}</span>
        </div>
        <div class="title">
          <span
            v-for="(title, titleId) in setConfig.titleArr"
            :key="titleId"
            :style="title.style"
            >{{ title.name }}</span
          >
        </div>
      </template>
      <!--工具栏之右侧工具按钮-->
      <template v-slot:tools>
        <!--自定义插槽，样式有问题。-->
        <vxe-form
          v-if="tableConfigObj.tableToolbar.search"
          style="background-color: transparent"
        >
          <vxe-form-item
            :title="tableConfigObj.tableSetting.searchLabel || '关键字：'"
            field="name"
          >
            <template v-slot>
              <vxe-input
                v-model="filterName"
                type="search"
                :placeholder="
                  tableConfigObj.tableSetting.searchPlaceholder ||
                  '请输入关键字'
                "
                size="small"
                @search-click="
                  $emit('searchFilterName', $event, filterName, tableDataList)
                "
              ></vxe-input>
            </template>
          </vxe-form-item>
        </vxe-form>
      </template>
      <!--自定义操作列插槽 operateCol-->
      <template v-slot:operateCol="{ row, column }">
        <span>
          <el-tooltip
            v-for="(item, index) in operateBtnList"
            :key="index"
            :content="item.tipMsg"
            placement="top"
            effect="light"
            :disabled="item.disabled === false || item.tipMsg ? false : true"
          >
            <vxe-button
              class="ml5 operateBtn"
              :class="operateBtnClassName(row, column, item)"
              :disabled="operateBtnIsDisabled(row, column, item)"
              :type="item.type || 'button'"
              :status="item.status || 'primary'"
              :size="item.size || 'mini'"
              @click="operateBtnClick(row, column, item)"
              v-if="operateBtnIsShow(row, column, item)"
              >{{ operateBtnShowName(row, column, item) }}</vxe-button
            >
          </el-tooltip>
          <!-- <slot
            :name="item.action"
            :row="row"
            :column="column"
            v-else
            :item="item"
          ></slot> -->
        </span>
      </template>
      <template v-slot:customCol="{ row, rowIndex, column, columnIndex }">
        <a v-if="column.own.btnCLick" class="pointer blue">{{
          row[column.own.code]
        }}</a>
        <slot
          v-else
          :name="column.own.code"
          :row="row"
          :rowIndex="rowIndex"
          :column="column"
          :columnIndex="columnIndex"
        ></slot>
      </template>
    </vxe-grid>
    <!--分页 mini/medium :pager-count="2"-->
    <vxe-pager
      v-if="tableConfigObj.tablePage.totalResult > 0"
      size="medium"
      :align="tableConfigObj.tablePage.pageAlign"
      :current-page="tableConfigObj.tablePage.currentPage"
      :page-size="tableConfigObj.tablePage.pageSize"
      :page-count="tableConfigObj.tablePage.pageCount"
      :total="tableConfigObj.tablePage.totalResult"
      :layouts="tableConfigObj.tablePage.layouts"
      @page-change="handlePageChange"
    ></vxe-pager>
  </div>
</template>

<script>
import XEUtils from "xe-utils";
import "./js/gridFormats.js";
import "./js/gridRenderer.js";
import * as gridAdpter from "./js/gridAdapter.js";
import { getVxeGridColoumnData } from "@/components/api/vxeGrid.js";

export default {
  name: "dataGrid",
  components: {
  },
  props: {
    gridRef: {
      //自定义列表ref
      type: String,
      default() {
        return "vxeGrid";
      },
    },
    gridData: {
    // 表格数据
      type: [Array],
      default() {
        return [];
      },
    },
    which: {
    // 第几个表格
      type: [Number, String],
      default() {
        return 1;
      },
    },
    isCustomData: {
    // 是否自定义列
      type: Boolean,
      default() {
        return true;
      },
    },
    customColumn: {
    // 自定义列 当isCustom === true 生效
      type: [Array],
      default() {
        return [];
      },
    },
    size: {
    // 表格尺寸大小
      type: String,
      default() {
        return "medium";
      },
    },
    loading: {
      type: Boolean,
      default() {
        return false;
      },
    },
    setConfig: {
      type: Object,
      default() {
        return {};
      },
    },
    height: {
    // 表格高度
      type: [Number, String],
      default() {
        return "auto"; //正常默认是auto
      },
    },
    max_height: {
    // 最大高度
      type: [String, Number],
      default() {
        return "800";
      },
    },
    seq: {
    // 序号
      type: Boolean,
      default() {
        return true;
      },
    },
    checkStyle: {
    // 是否有选择
      type: String,
      default() {
        return "false"; //"checkbox"
      },
    },
    allAlign: {
    // 是否居中
      type: String,
      default() {
        return "center";
      },
    },
    showOverflow: {
      //ellipsis（只显示省略号）,title（并且显示为原生 title）,tooltip（并且显示为 tooltip 提示）
      type: [Boolean, String],
      default() {
        return "ellipsis";
      },
    },
    border: {
      //表格边框。border=false|default 默认显示边框； border=true|full 显示完整边框； border=outer 显示外边框； border=inner 显示内边框； border=none 去掉所有边框。
      type: String,
      default: function () {
        return "full";
      },
    },
    stripe: {
      //stripe属性可以创建带斑马纹的表格。它接受一个Boolean，默认为false，设置为true即为启用。
      type: Boolean,
      default() {
        return true;
      },
    },
    isHighLightCurrRow: {
      //配置highlight-current-row属性即可实现选中行数据。
      type: Boolean,
      default() {
        return false;
      },
    },
    isHighLighthoverRow: {
      //配置highlight-hover-row属性即可实现鼠标划过行加高亮。
      type: Boolean,
      default() {
        return true;
      },
    },
    isHighLightCurrcolumn: {
      //配置highlight-current-column属性即可实现列选中。
      type: Boolean,
      default() {
        return true;
      },
    },
    isHighLighthovercolumn: {
      //配置highlight-hover-column属性即可实现鼠标划过列加高亮。
      type: Boolean,
      default() {
        return true;
      },
    },
    emptyRenderCon: {
      //空内容渲染配置项
      type: [String],
      default() {
        return "";
      },
    },
    treeMethod: {
      type: Function,
      default() {
        return null;
      },
    },
    activeCellMethodCallBack: {
      type: Function,
      default() {
        return null;
      },
    },
  },
  data() {
    return {
      cacheData: {}, // 数据缓存
      filterName: "", //搜索的数据
      validRules: {}, //表格的规则验证
      gridColumnData: [], //配置列
      sumCols: [], //合计列
      toolbarData: [], //按钮的数据
      primitiveColumn: [], //原始列，做一个备份用
      showEdit: false, //是否显示表格编辑dialog
      selectRow: null, //选择行，配和showEdit使用
      CRUDformData: {}, //表格自带的可编辑 表单配置列
      formRules: {}, //表格自带的可编辑 表单数据 的规则
      columnsName: [], //所有列的name。可拓展成方法
      gridShowData: [],
      tableConfigObj: {
        treeConfig: {
          lazy: true,
          children: "children",
          hasChild: "hasChild",
          loadMethod: this.loadChilerenMethod,
          toggleMethod: this.toggleMethod,
          expandAll: false,
          accordion: false,
          indent: 10,
        },
        tableSetting: {
          headerRowClassName: "", //表头行加classname
          footerRowClassName: "", //表尾行加classname
          footerRowStyle: (column) => {
            return "";
          },
          headerRowStyle: (column) => {
            return "";
          },
          searchLabel: "", //
          searchPlaceholder: "", //
          isShowGridTitle: false, //是否显示格标题
          title: "数据列表",
          border: "default", // 是否带有边框 default（默认） full(完整边框) outer(外边框) inner(内边框) none(无边框)
          isEdit: false, //是否可编辑
          isLock: false, //是否锁定
          totalTag: false, //是否合计
          isRowSpan: {
            // 需要合并的单元格
            rowSpan: [], // 相同就合并
            span: [], // rowSpan相同才合并span中的内容
            noneList: [], // 不需要合并的内容
          },
          showHeader: true, // 是否显示表头
          rowChecked: "cell", //行选中row or cell
          showCheckboxHeader: true,
          trigger: "click",
          mode: "cell",
          operate: false, //操作列
          operateWidth: 260, //操作列宽度
          colAlign: "center", //操作列排列方式
          isShowAddBtn: true, //默认显示新增按钮
          isShowDeleteBtn: true, //默认显示删除按钮
          isShowEditBtn: true, //默认显示编辑按钮
          isShowDetailBtn: true, //默认显示详情按钮
          pageAlgin: "center",
          isSeqConfig: false,
          isPageConfig: false,
          tableColConfig: {},
        },
        //工具栏的按钮设置。
        tableToolbar: {
          buttons: [],
          search: false, //是否显示搜索框
          import: false, //是否显示上传
          export: false, //是否显示下载
          zoom: false, // 是否显示全屏
          custom: false,
          // resizable: {
          //   storage: true,
          // },
          // //设置异常显示列
          // custom: {
          //   storage: false, //列的拉动宽度都会进行缓存。****************************
          //   checkMethod: this.checkColumnMethod, //复选框和序列号不能勾选
          // },
        },
        tablePage: {
          pageAlign: "center",
          totalResult: 0,
          currentPage: 1,
          pageSize: 10,
          pageCount: 1,
          layouts: [
            "PrevPage",
            "JumpNumber",
            "NextPage",
            "FullJump",
            "Sizes",
            "Total",
          ],
        }, //分页
      },
    };
  },
  watch: {
    setConfig: {
      handler(val) {
        this.tableConfigObj = XEUtils.merge(
          this.tableConfigObj,
          this.setConfig
        );
      },
      deep: true,
      immediate: true,
    },
    "tableConfigObj.tablePage": {
      handler(val) {
        this.$emit("upadteTablePage", val);
      },
      deep: true,
    },
    customColumn: {
      handler(val) {
        if (this.isCustomData) {
          this.initGridColumnData(this.customColumn);
        }
      },
      deep: true,
    },
    gridColumnData: {
      handler(val) {
        this.$emit("upadteCustomColumn", val);
      },
      deep: true,
    },
    gridData: {
      handler(val) {
        this.gridShowData = XEUtils.clone(this.gridData, true);
      },
      deep: true,
      immediate: true,
    },
    filterName: {
      //全局搜索内容变化后实时更新列表内容
      handler(val) {
        if (this.tableConfigObj.tableSetting.isPageConfig) {
          this.getSearchGridData();
          this.tableConfigObj.tablePage.totalResult =
            this.gridShowData.length || 0;
          this.tableConfigObj.tablePage.currentPage = 1;
        }
        this.$emit("searchFilterNameCallback", val, this.gridShowData);
      },
      deep: true,
    },
  },
  computed: {
    //表数据处理，主要加搜索
    tableDataList() {
      if (this.tableConfigObj.tableSetting.isPageConfig) {
        return XEUtils.filter(this.gridShowData, (item, idx) => {
          return (
            idx >=
              (this.tableConfigObj.tablePage.currentPage - 1) *
                this.tableConfigObj.tablePage.pageSize &&
            idx <
              this.tableConfigObj.tablePage.currentPage *
                this.tableConfigObj.tablePage.pageSize
          );
        });
      } else {
        this.getSearchGridData();
      }
      return this.gridShowData;
    },
    //列的处理，主要有适配，格式化，校验规则，初始化业务需要到的功能。
    columnDataList(val) {
      this.primitiveColumn = XEUtils.clone(this.gridColumnData, true);
      if (this.gridColumnData.length > 0) {
        // 把业务列适配到vxetable表格上
        let convertColObj = gridAdpter.adapterColumns(this);
        //适配后的列
        this.gridColumnData = convertColObj.aryCols;
        //表格的校验和 弹出form表单窗口的校验规则是一样的
        this.formRules = this.validRules = convertColObj.validRules;
        //加上序列号和选择框
        this.mergeCommonSt();
        //初始化列
        this.initCols();
      }
      return this.gridColumnData;
    },
    operateBtnList() {
      //操作列按钮数据
      let defaultOperateBtnData = [
        {
          action: "add",
          name: "新增",
          isVisible: this.tableConfigObj.tableSetting.isShowAddBtn,
        },
        {
          action: "delete",
          name: "删除",
          isVisible: this.tableConfigObj.tableSetting.isShowDeleteBtn,
        },
        { action: "save", name: "保存", isVisible: false },
        { action: "cancel", name: "取消", isVisible: false },
        {
          action: "edit",
          name: "编辑",
          isVisible: this.tableConfigObj.tableSetting.isShowEditBtn,
        },
        {
          action: "detail",
          name: "详情",
          isVisible: this.tableConfigObj.tableSetting.isShowDetailBtn,
        },
      ];

      // console.log(78787878,defaultOperateBtnData.concat(this.tableConfigObj.tableSetting.operateBtnData))
      return defaultOperateBtnData.concat(
        this.tableConfigObj.tableSetting.operateBtnData
      );
    },
  },
  created() {
    this.getColumnData();
  },
  mounted() {
    this.$nextTick(() => {});
  },
  methods: {
    getSearchGridData() {
      if (this.tableConfigObj.tableToolbar.search) {
        const filterName = XEUtils.toString(this.filterName)
          .trim()
          .toLowerCase();
        if (filterName) {
          const filterRE = new RegExp(filterName, "gi");
          let searchProps = XEUtils.map(this.gridColumnData, (item) => {
            return item.code;
          });
          searchProps = XEUtils.filter(searchProps, (item) => !!item);
          const rest = XEUtils.filter(this.gridData, (item) =>
            XEUtils.some(
              searchProps,
              (key) =>
                XEUtils.toString(item[key]).toLowerCase().indexOf(filterName) >
                -1
            )
          );
          this.gridShowData = XEUtils.map(rest, (row) => {
            const item = XEUtils.clone(row, true);
            XEUtils.arrayEach(searchProps, (key) => {
              item[key] = XEUtils.toString(item[key]).replace(
                filterRE,
                (match) => `${match}`
              );
            });
            return item;
          });
        } else {
          this.gridShowData = this.gridData;
        }
      }
    },
    getColumnData() {
      //初始化列数据
      // this.tableConfigObj = Object.assign(this.tableConfigObj, this.setConfig);
      if (this.isCustomData) {
        this.initGridColumnData(this.customColumn);
      } else {
        let params = {};
        getVxeGridColoumnData(params).then((res) => {
          this.initGridColumnData(res.data);
        });
      }
    },
    //赋值列数据
    initGridColumnData(data) {
      this.gridColumnData = data;
    },
    loadCacheData(eleCode, data) {
      this.cacheData[eleCode] = data;
    },
    editActivedEvent({ row, column }, event) {
      // 当激活编辑时，重新更新远程下拉值
      let eleCode =
        column.own.fromSource ||
        row["__rep_" + column.own.code] ||
        column.own.code; // row["__rep_" + eleCode]数据行，
      let isEditVal = row.isEditObj
        ? row.isEditObj[eleCode]
        : column.own.isEdit;
      if (column.type === "select" || column.type === "selectTree") {
        // 当激活编辑时，重新更新远程下拉值 替换数据要素，存在替换数据要素时，优先取该要素值;
        if (this.cacheData[eleCode]) {
          column.editRender.options = this.cacheData[eleCode];
        } else {
          let params = { elementCode: eleCode };
          getVxeGridSelectData(params).then((res) => {
            if (res.resultCode === 200) {
              this.loadCacheData(eleCode, res.data);
              column.editRender.options = res.data;
            }
          });
        }
      } else if (column.type === "input") {
        column.editRender.props.readonly = !isEditVal;
      }
      this.$emit("gridEditActiveCallback", { row, column }, event);
    },
    editClosedEvent({ row, column }, event) {
      //关闭列编辑
      this.$emit("gridEditCloseCallback", { row, column }, event);
    },
    //初始化列头数据
    initCols() {
      let _this = this;
      if (!XEUtils.isArray(this.gridColumnData)) {
        return this.gridColumnData;
      }
      let colsNameAry = []; //列的code，
      let tempCols = this.gridColumnData.map((it, index) => {
        //合计
        if (_this.tableConfigObj.tableSetting.totalTag && it.totalTag) {
          _this.sumCols.push(it.code);
        }
        //除序号和复选框所有的列的code
        if (it.code) {
          colsNameAry.push(it.code);
        }
        return it;
      });
      this.columnsName = colsNameAry;
    },
    //添加复选框和序列号 Object.assign
    mergeCommonSt() {
      if (this.seq) {
        this.gridColumnData.unshift({
          type: "seq",
          width: 60,
          title: "序号",
          resizable: false,
        }); //属性待加
      }
      if (this.checkStyle !== "false") {
        //  字符串参数为false时，不添加类型
        this.gridColumnData.unshift({
          type: this.checkStyle,
          title: "",
          width: 50,
          resizable: false, //序列和选择框不能拖动
        }); //属性待加
      }
    },
    // setColumnOptions(code, value) {
    //   //根据code值获取单个列的数据
    //   const colData =
    //     this.columnDataList && this.columnDataList.length
    //       ? this.columnDataList.filter((item) => item.code === code)
    //       : [];
    //   colData.length ? (colData[0].editRender.options = value) : null;
    // },

    //分页信息
    handlePageChange({ currentPage, pageSize }) {
      this.tableConfigObj.tablePage.currentPage = currentPage;
      this.tableConfigObj.tablePage.pageSize = pageSize;
      this.$emit("pageChangeCallback", currentPage, pageSize);
    },
    cellStyle({ row, column }) {
      //单元格样式
      row.cellStyleObj = {};
      // row.cellStyleObj.myIcon = row.myIcon == 3 ? "background-color:#f0f;" : "";
      this.$emit("cellStyleCallBack", row, column);
      if (
        row.cellStyleObj &&
        column.own &&
        column.own.code &&
        row.cellStyleObj[column.own.code]
      ) {
        return row.cellStyleObj[column.own.code];
      }
    },
    headerCellStyle({ column }) {
      //表头单元格的样式
      if (column.own && column.own.headerCellStyle) {
        return column.own.headerCellStyle;
      }
    },
    footerCellStyle({ column }) {
      // 表尾单元格样式
      if (column.own && column.own.footerCellStyle) {
        return column.own.footerCellStyle;
      }
    },
    cellClassName({ row, column }) {
      //给单元格附加 className
      row.cellClassNameObj = {};
      row.cellClassNameObj.myIcon = row.myIcon == 3 ? "iconClass" : "";
      this.$emit("cellClassNameCallBack", row, column);
      if (
        row.cellClassNameObj &&
        column.own &&
        column.own.code &&
        row.cellClassNameObj[column.own.code]
      ) {
        return row.cellClassNameObj[column.own.code];
      }
    },
    headerCellClassName({ column }) {
      //给表头单元格附加 className
      if (column.own && column.own.headerCellClassName) {
        return column.own.headerCellClassName;
      }
    },
    footerCellClassName({ column }) {
      //给表尾单元格附加 className
      if (column.own && column.own.footerCellClassName) {
        return column.own.footerCellClassName;
      }
    },
    rowClassName({ row }) {
      //给行格附加 className
      this.$emit("rowClassNameCallBack", row);
      if (row.rowClassName) {
        return row.rowClassName;
      }
    },
    rowStyle({ row }) {
      //行附加样式
      this.$emit("rowStyleCallBack", row);
      if (row.rowStyle) {
        return row.rowStyle;
      }
    },
    operateBtnClassName(row, column, btnItem) {
      //添加操作列按钮的classname
      row.classNameObj = {};
      this.$emit("operateBtnClassNameCallback", row, column, btnItem);
      if (row.classNameObj && row.classNameObj[btnItem.action]) {
        return row.classNameObj[btnItem.action];
      } else {
        return "btnColorGreen";
      }
    },
    operateBtnShowName(row, column, btnItem) {
      //操作列按钮显示名称重写
      row.showNameObj = {};
      this.$emit("operateBtnShowNameCallback", row, column, btnItem);
      if (
        row.showNameObj &&
        row.showNameObj[btnItem.action] &&
        btnItem.action != "save" &&
        btnItem.action != "cancel"
      ) {
        return row.showNameObj[btnItem.action];
      } else {
        return btnItem.name;
      }
    },
    operateBtnIsDisabled(row, column, btnItem) {
      //操作列按钮禁用状态设置
      row.isDisableObj = {};
      this.$emit("operateBtnIsDisabledCallback", row, column, btnItem);
      if (
        row.isDisableObj &&
        (row.isDisableObj[btnItem.action] == false ||
          row.isDisableObj[btnItem.action] == true) &&
        btnItem.action != "save" &&
        btnItem.action != "cancel"
      ) {
        return row.isDisableObj[btnItem.action];
      } else {
        return !!btnItem.isDisabled;
      }
    },
    operateBtnIsShow(row, column, btnItem) {
      //操作列按钮的显示隐藏状态设置
      row.isShowObj = {};
      this.$emit("operateBtnIsShowCallback", row, column, btnItem);
      if (
        row.isShowObj &&
        (row.isShowObj[btnItem.action] == false ||
          row.isShowObj[btnItem.action] == true) &&
        btnItem.action != "save" &&
        btnItem.action != "cancel"
      ) {
        return row.isShowObj[btnItem.action];
      } else {
        return !!btnItem.isVisible;
      }
    },

    operateBtnClick(row, column, btnItem) {
      //操作列按钮点击事件
      if (btnItem.action == "delete") {
        //操作列中删除按钮点击
        this.$confirm("此操作将永久删除该数据, 是否继续?", "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        })
          .then(() => {
            // if (!row) {
            //   this.$refs[this.gridRef].removeCheckboxRow();
            // } else {
            //   this.$refs[this.gridRef].remove(row);
            // this.$message({
            //   type: "success",
            //   message: "删除成功!",
            // });
            // }
            this.$emit("operateBtnClickCallback", row, column, btnItem);
          })
          .catch(() => {
            // this.$message({
            //   type: "info",
            //   message: "已取消删除",
            // });
          });
      } else if (btnItem.action == "save") {
        //操作列中保存按钮点击
        this.$refs[this.gridRef].clearActived().then(() => {
          this.$emit("operateBtnClickCallback", row, column, btnItem);
        });
      } else if (btnItem.action == "cancel") {
        //操作列中取消按钮点击
        const xTable = this.$refs[this.gridRef];
        xTable.clearActived().then(() => {
          // 还原行数据
          xTable.revertData(row);
        });
      } else if (btnItem.action == "cancel") {
        //操作列中编辑按钮点击
        if (this.tableConfigObj.tableSetting.isEdit) {
          this.$refs[this.gridRef].setActiveRow(row);
        } else {
          this.$emit("operateBtnClickCallback", row, column, btnItem);
        }
      } else {
        this.$emit("operateBtnClickCallback", row, column, btnItem);
      }
    },
    /*新增数据
     *obj：新增的数据，
     * rowNo：null 默认第一行。-1最后一行插入
     *isModel：是否弹窗方式
     */
    insertRow(obj, rowNo, isModel) {
      obj = obj || {};
      rowNo = rowNo ? -1 : null;
      isModel = isModel || false;
      if (!XEUtils.isPlainObject(obj)) {
        return;
      }
      if (isModel) {
        let colsNameObj = {};
        if (this.columnsName.length > 0) {
          this.columnsName.forEach((it, index) => {
            //新增时，默认都给空值
            colsNameObj[it] = "";
          });
        }
        this.CRUDformData = colsNameObj;
        Object.assign(this.CRUDformData, obj);
        this.selectRow = null;
        this.showEdit = true;
      } else {
        this.$refs[this.gridRef].insertAt(obj, rowNo);
      }
    },
    setAllTreeGridExpand() {
      //树列表时展开所有
      this.$refs[this.gridRef].setAllTreeExpand(true);
    },
    clearTreeGridExpand() {
      //树列表时关闭所有
      this.$refs[this.gridRef].clearTreeExpand();
    },

    cellClickEvent({ row, column }) {
      //单元格被点击时会触发该事件
      this.$emit("cellClickEventCallBack", row, column);
    },
    headerCellClickEvent({ column }) {
      //表头单元格被点击时会触发该事件
      this.$emit("headerCellClickEventCallBack", column);
    },
    footerCellClickEvent({ column }) {
      //表尾单元格被点击时会触发该事件
      this.$emit("footerCellClickEventCallBack", column);
    },
    cellDBLClickEvent({ row, column }) {
      //单元格被双击时会触发该事件
      this.$emit("cellDBLClickEventCallBack", row, column);
    },
    headerCellDBLClickEvent({ column }) {
      //表头单元格被双击时会触发该事件
      this.$emit("headerCellDBLClickEventCallBack", column);
    },
    footerCellDBLClickEvent({ column }) {
      //表尾单元格被双击时会触发该事件
      this.$emit("footerCellDBLClickEventCallBack", column);
    },
    cellMouseenterEvent({ row, column }) {
      //只对 tooltip-config 配置时有效，当鼠标移动到单元格时会触发该事件
      this.$emit("cellMouseenterEventCallBack", row, column);
    },
    cellMouseleaveEvent({ row, column }) {
      //只对 tooltip-config 配置时有效，当鼠标移开单元格时会触发该事件
      this.$emit("cellMouseleaveEventCallBack", row, column);
    },
    scrollEvent({
      type,
      scrollTop,
      scrollLeft,
      scrollHeight,
      scrollWidth,
      bodyWidth,
      bodyHeight,
    }) {
      //表格滚动时会触发该事件
      this.$emit(
        "scrollEventCallBack",
        type,
        scrollTop,
        scrollLeft,
        scrollHeight,
        scrollWidth,
        bodyWidth,
        bodyHeight
      );
    },
    //禁用
    activeCellMethod({ row, rowIndex, column, columnIndex }) {
      if (this.activeCellMethodCallBack) {
        return this.activeCellMethodCallBack(
          row,
          rowIndex,
          column,
          columnIndex
        );
      }
      return !!column.own.isEdit;
    },
    checkboxAll({ checked }) {
      //只对 type=checkbox 有效，当手动勾选全选时触发的事件
      this.$emit("checkboxAllCallback", checked);
    },
    checkboxChange({ checked, row, column }) {
      //只对 type=checkbox 有效，当手动勾选并且值发生改变时触发的事件
      this.$emit("checkboxChangeCallback", checked, row, column);
    },
    tooltipContentMethod({ row, column }) {
      //重写默认的提示内容
      if (row) {
        // let columnVal = row[column.property];
        row.tooltipContentObj = {};
        this.$emit("tooltipContentMethodCallback", row, column);
        return row.tooltipContentObj[column.property];
      }
    },
    loadCheckMethod({ row }) {
      //是否允许选中
      if (row) {
        row.isEditCheckbox = true;
        this.$emit("loadCheckMethodCallback", row);
        return !!row.isEditCheckbox;
      }
    },
    loadChilerenMethod({ row }) {
      // 异步加载子节点,树形懒加载
      const children = this.treeMethod(row);
      return new Promise((resolve) => {
        resolve(children);
      });
    },
    toggleMethod({ expanded, row, column }) {
      // 树形展开关闭触发前调用，通过返回值决定是否允许执行
      this.$emit("toggleMethodCallback", expanded, row, column);
    },
    getCurrentRecord() {
      //获取当前高亮行的数据
      return this.$refs[this.gridRef].getCurrentRecord();
    },
    getCurrentColumn() {
      //获取当前高亮的列的数据
      return this.$refs[this.gridRef].getCurrentColumn();
    },
    loadData(data) {
      //表格数据重载
      data = XEUtils.isArray(data) ? data : [];
      return this.$refs[this.gridRef].loadData(data);
    },
    refreshGrid(data) {
      //加载数据并清除所有状态
      data = XEUtils.isArray(data) ? data : [];
      this.$refs[this.gridRef].reloadData(data);
    },
    refreshColumn() {
      //刷新列配置
      this.$refs[this.gridRef].refreshColumn();
    },
    getTableColumn() {
      //获取当前表格的列（收集到的全量列、全量表头列、处理条件之后的全量表头列、当前渲染中的表头列）
      return this.$refs[this.gridRef].getTableColumn();
    },
    getTableData() {
      //获取当前表格的数据（完整的全量表体数据、处理条件之后的全量表体数据、当前渲染中的表体数据、当前渲染中的表尾数据）
      return this.$refs[this.gridRef].getTableData();
    },
    getRowData(rowIndex) {
      //通过行索引获取某条数据，为空则获取所有数据
      if (XEUtils.isNumber(rowIndex)) {
        return this.$refs[this.gridRef].getData(rowIndex);
      } else {
        return this.$refs[this.gridRef].getData();
      }
    },
    getColData(columnIndex) {
      //通过列索引获取某列数据，为空则获取所有数据
      if (XEUtils.isNumber(columnIndex)) {
        return this.$refs[this.gridRef].getColumns(columnIndex);
      } else {
        return this.$refs[this.gridRef].getColumns();
      }
    },
    getColDataByFieldName(fieldName) {
      //根据列名获取列数据
      fieldName = fieldName || "";
      return this.$refs[this.gridRef].getColumnByField(fieldName);
    },
    getRowDataByRowId(rowId) {
      //根据rowId获取某一行的数据
      return this.$refs[this.gridRef].getRowById(rowId);
    },
    getRadioData() {
      //获取单选选中数据
      return this.$refs[this.gridRef].getRadioRecord();
    },
    getCheckboxData() {
      //获取多选选中数据
      return this.$refs[this.gridRef].getCheckboxRecords();
    },
    //修改筛选列表
    setFilter(column, options) {
      this.$refs[this.gridRef].setFilter(column, options);
    },
    removeCheckboxRow() {
      //删除当前行选中的行数据
      return this.$refs[this.gridRef].removeCurrentRow();
    },
    getRecordset() {
      //获取增删改的数据集
      return this.$refs[this.gridRef].getRecordset();
    },
    getInsertData() {
      //获取新增数据
      return this.$refs[this.gridRef].getInsertRecords();
    },
    getRemoveData() {
      //获取删除数据
      return this.$refs[this.gridRef].getRemoveRecords();
    },
    getUpdateData() {
      //获取修改的数据
      return this.$refs[this.gridRef].getUpdateRecords();
    },
    setRadioRow(row) {
      //type=radio，设置某一行为选中状态
      row = row || [];
      this.$refs[this.gridRef].setRadioRow(row);
    },
    setCheckboxRow(rows, checked) {
      //type=checkbox 设置行为选中状态，第二个参数为选中与否
      rows = rows || [];
      this.$refs[this.gridRef].setCheckboxRow(rows, checked);
    },
    setAllCheckboxRow(checked) {
      //type=checkbox 全选和取消
      let isCheck = !!checked;
      this.$refs[this.gridRef].setAllCheckboxRow(isCheck);
    },
    hideColumn(column) {
      //隐藏列
      column = XEUtils.isPlainObject(column) ? column : {};
      this.$refs[this.gridRef].hideColumn(column);
    },
    showColumn(column) {
      //显示列
      column = XEUtils.isPlainObject(column) ? column : {};
      this.$refs[this.gridRef].showColumn(column);
    },
    maximizeGrid() {
      // 表格最大化
      return this.$refs[this.gridRef].maximize();
    },
    revertGrid() {
      // 表格还原
      return this.$refs[this.gridRef].revert();
    },
    clearData(rows, field) {
      //清空单元格内容，传行清行，传列清列
      this.$refs[this.gridRef].clearData(rows, field);
    },
    validate(rows, fn) {
      //表格校验函数，如果指定 row 或 rows 则校验指定一行或多行，否则校验整个表格
      let callback = this.$refs[this.gridRef].validate(rows, fn);
      return callback;
    },
    fullValidate(rows, fn) {
      //表格完整校验函数，和 validate 的区别就是会对全量数据的所有规则进行完整校验
      let callback = this.$refs[this.gridRef].validate(rows, fn);
      return callback;
    },
    clearValidate() {
      //手动清除校验
      this.$refs[this.gridRef].clearValidate();
    },
    clearAll() {
      //清除表格所有条件，还原到初始状态
      this.$refs[this.gridRef].clearAll();
    },
    updateFooter() {
      //手动更新表尾
      this.$refs[this.gridRef].updateFooter();
    },
    recalculate() {
      //重新计算表格
      this.$refs[this.gridRef].recalculate();
    },
    scrollToRow(row) {
      //如果有滚动条，则滚动到对应的行（比如定位到某一行）
      row && this.$refs[this.gridRef].scrollToRow(row);
    },
    scrollToColumn(column) {
      //如果有滚动条，则滚动到对应的列（比如定位到某一列）
      column && this.$refs[this.gridRef].scrollToColumn(column);
    },
    zoom() {
      //缩小放大表格
      this.$refs[this.gridRef].zoom();
    },

    checkColumnMethod({ column }) {
      //序号和复选框不让显示隐藏
      if (column.type === "seq" || column.type === "checkbox") {
        return false;
      }
      return true;
    },
    colspanMethod({ row, rowIndex, column, columnIndex, data }) {
      //合并格式化单元格
    },
    rowSpanMethod({ row, $rowIndex, column, data }) {
      //合并单元格
      if (this.tableConfigObj.tableSetting.isRowSpan.noneSpan) {
        const list = this.rowSpanNoMethod({ row, $rowIndex, column, data });
        if (list.length) return;
      }
      if (
        this.tableConfigObj.tableSetting.isRowSpan.rowSpan &&
        this.tableConfigObj.tableSetting.isRowSpan.rowSpan.length &&
        row[column.property] &&
        this.tableConfigObj.tableSetting.isRowSpan.rowSpan.includes(
          column.property
        )
      ) {
        return this.spanMethods({ row, $rowIndex, column, data });
      } else if (
        this.tableConfigObj.tableSetting.isRowSpan.span &&
        this.tableConfigObj.tableSetting.isRowSpan.span.length &&
        row[column.property] &&
        this.tableConfigObj.tableSetting.isRowSpan.span.includes(
          column.property
        )
      ) {
        return this.spanMethods({ row, $rowIndex, column, data }, "span");
      }
    },
    spanMethods({ row, $rowIndex, column, data }, span) {
      const cellValue = row[column.property];
      let prevRow = data[$rowIndex - 1];
      let nextRow = data[$rowIndex + 1];
      const rowSpan =
        span && this.tableConfigObj.tableSetting.isRowSpan.rowSpan[0];
      if (
        prevRow &&
        prevRow[column.property] === cellValue &&
        (rowSpan ? prevRow[rowSpan] === row[rowSpan] : true)
      ) {
        return { rowspan: 0, colspan: 0 };
      } else {
        let countRowSpan = 1;
        while (
          nextRow &&
          nextRow[column.property] === cellValue &&
          (rowSpan ? nextRow[rowSpan] === row[rowSpan] : true)
        ) {
          nextRow = data[++countRowSpan + $rowIndex];
        }
        if (countRowSpan > 1) {
          return { rowspan: countRowSpan, colspan: 1 };
        }
      }
    },
    rowSpanNoMethod({ row, $rowIndex, column, data }) {
      const noneSpan =
        this.tableConfigObj.tableSetting.isRowSpan.noneSpan || {};
      const list = [];
      for (let i in noneSpan) {
        noneSpan[i] &&
          noneSpan[i].length &&
          noneSpan[i].includes(row[i]) &&
          list.push(true);
      }
      return list;
    },

    footerSpanMethod({ $rowIndex, column, columnIndex, $columnIndex, data }) {
      // 表尾合并
    },
    //表格尾部的方法，主要做合计
    footerMethod({ columns, data }) {
      if (!this.tableConfigObj.tableSetting.totalTag) return;
      return [
        columns.map((column, columnIndex) => {
          if (columnIndex === 0) {
            return "合计";
          }
          if (this.sumCols.includes(column.property)) {
            return XEUtils.sum(data, column.property);
          }
          return null;
        }),
      ];
    },
    //导出
    exportData() {
      this.$refs[this.gridRef].openExport({
        // 默认勾选源
        original: true,
      });
    },
    //导入
    importData() {
      this.$refs[this.gridRef].importData();
    },
    //打印 ,data 参数自定义 打印的表头
    printEvent() {
      this.$refs[this.gridRef].print();
    },
  },
};
</script>

<style lang="less" scoped>
.vxe-pager {
  margin-top: 17px;
}
.title {
  float: left;
  img {
    display: inline-block;
    vertical-align: middle;
  }
  span {
    display: inline-block;
    vertical-align: middle;
    font-size: 15px;
    font-weight: 600;
    color: #333;
    margin-left: 3px;
  }
}
.tool-btn {
  font-size: 18px;
  cursor: pointer;
}
.keyword-lighten {
  color: #000;
  background-color: #ffff00;
}
.vxe-table .vxe-cell {
  padding: 0 5px;
  white-space: nowrap;
  text-overflow: ellipsis;
  overflow: hidden;
}

.gridContainer {
  background-color: #fff;
  // box-shadow: 0 8px 20px 0 rgba(172, 175, 184, 0.1);\

  // height: calc(100vh - 150px);
}
.first-toolbar {
  position: absolute;
  left: -25px;
  top: 50px;
  z-index: 1;
}

.first-toolbar span {
  display: block;
  width: 16px;
  height: 16px;
  background-color: #409eff;
  border-radius: 50%;
  margin: 2px 5px;
  font-size: 12px;
  color: #fff;
  line-height: 14px;
  text-align: center;
  cursor: pointer;
}
</style>
<style lang="less">
@import "../../style/variables.less";
.btnColorGreen {
  color: #39c984;
}
.btnColorGray {
  color: #bfbfbf;
}
.dynamicHeighgt {
  &,
  .gridContainer,
  .vxe-grid,
  .vxe-table,
  .vxe-table--main-wrapper {
    height: 100%;
  }
}
.vxe-toolbar {
  height: auto !important;
  margin-bottom: 0px !important;
  background: #f0f0f0 !important;
}
.vxe-table--header {
  background: @tableTileBg;
}
.vxe-table .vxe-body--row {
  // 当前选中行样式
  &.row--current,
  &:hover {
    background: @menuBgActive !important;
  }
  &.row--stripe {
    // 斑马行样式
    background: #eeeeef;
  }
}
.vxe-pager.is--background .vxe-pager--jump-next:not(.is--disabled).is--active,
.vxe-pager.is--background .vxe-pager--jump-prev:not(.is--disabled).is--active,
.vxe-pager.is--background .vxe-pager--num-btn:not(.is--disabled).is--active,
.vxe-pager.is--perfect .vxe-pager--jump-next:not(.is--disabled).is--active,
.vxe-pager.is--perfect .vxe-pager--jump-prev:not(.is--disabled).is--active,
.vxe-pager.is--perfect .vxe-pager--num-btn:not(.is--disabled).is--active {
  background: @tableTileBg !important;
}
</style>
